package stegnos.tests;

import java.awt.Font;

import org.quark.stegnos.Analysis;
import org.quark.stegnos.Steganos;

import g4p_controls.*;
import processing.core.PApplet;
import processing.core.PImage;

public class StegMakerDemo extends PApplet {

	final String statusIconFile = "steg/optionset.png";

	int winX = 100, winY = 50;

	Selector carrierSelector, burdenSelector, steganSelector;

	public class Selector {
		PImage img = null;
		String text = null;
		
		PApplet papp;		
		GWindow window = null;
		GButton button;
		GImageToggleButton status;
		String fname;
		String title;
		String exts;
		String types;
		
		public Selector(PApplet papplet, GButton button, GImageToggleButton status, String title, String exts, String types) {
			this(papplet, button, status);
			this.title = title;
			this.exts = exts;
			this.types = types;
			status.setState(1);
		}

		public Selector(PApplet papplet, GButton button, GImageToggleButton status) {
			super();
			this.papp = papplet;
			this.button = button;
			this.status = status;
			status.setState(1);
		}

		// Use to invalidate
		public void invalidate(GImageToggleButton imagetogglebutton, GEvent event){
			if(window != null){
				window.forceClose();
				window = null;
				img = null;
				fname = null;
				status.setState(1);
				performAnalysis();	
			}
		}

		public boolean isValid(){
			return status.getState() == 0;
		}

		public void makeStegan(GButton button, GEvent event) {
			// Whatever happens close the current window
			if(window != null){
				window.forceClose();
				window = null;
			}
			if(performAnalysis()){
				PImage temp  = null;
				String pword = txfPassword.getText().trim();
				status.setState(1);
				// Attempt to make the stegan
				if(burdenSelector.img != null)
					temp = Steganos.embedImage(pword, carrierSelector.img, burdenSelector.img);
				else
					temp = Steganos.embedText(pword, carrierSelector.img, burdenSelector.text);
				if(temp != null) {
					img = temp;
					window = new GWindow(papp, title, winX + 100, winY + 100, temp.width, temp.height, false, JAVA2D);
					window.setOnTop(false);
					window.papplet.background(240);
					window.papplet.image(img, 0, 0);
					status.setState(0);
				}
			}
		}

		public void saveStegan(GButton button, GEvent event) {
			if(img != null){
				String fname = G4P.selectOutput(title, exts, types);
				// Check that we have something different
				if(fname != null && fname.length() > 0){
					img.save(fname);
				}
			}

		}

		public void change(GButton button, GEvent event){
			String fn = G4P.selectInput(title, exts, types);
			// Check that we have something different
			if(fn != null && fn.length() > 0 && !fn.equalsIgnoreCase(fname)){
				fname = fn;
				int p = fname.lastIndexOf(".");
				String ext = fname.substring(p + 1);
				if(ext.equalsIgnoreCase("txt"))
					makeTextWindow();
				else
					makeImageWindow();
				performAnalysis();			}
		}
	
		private void makeImageWindow(){
			img = loadImage(fname);
			text = null;
			if(img != null){
				if(window != null){
					window.forceClose();
					window = null;
				}
				window = new GWindow(papp, title, winX + 100, winY + 100, img.width, img.height, false, JAVA2D);
				window.setOnTop(false);
				window.papplet.background(240);
				window.papplet.image(img, 0, 0);
				status.setState(0);
			}
		}

		private void makeTextWindow(){
			img = null;
			String[] lines = loadStrings(fname);
			String line = join(lines, "\n");
			if(line.length() > 0){
				text = line;
				if(window != null){
					window.forceClose();
					window = null;
				}
				window = new GWindow(papp, title, winX + 100, winY + 100, 500, 400, false, JAVA2D);
				window.setOnTop(false);
				window.papplet.background(240);
				window.papplet.fill(0);
				window.papplet.text(text, 10, 10, 480, 380);
				status.setState(0);
			}
		}

	}


	public void setup(){
		size(300, 540, JAVA2D);
		createGUI();

	}

	public void getFramePosition(){
		if(frame != null){
			winX = frame.getLocation().x;
			winY = frame.getLocation().y;
		}
	}
	
	public void draw(){
		background(32,168,32);

	}

	public boolean performAnalysis(){
		if(carrierSelector.isValid() && burdenSelector.isValid()){
			Analysis a;
			if(burdenSelector.img != null)
				a = Steganos.analyze(carrierSelector.img, burdenSelector.img);
			else
				a = Steganos.analyze(carrierSelector.img, burdenSelector.text);
			lblAnalysis.setText(a.text);
			return a.approved;
		}
		else {
			lblAnalysis.setText("Must specify both carrier and\nburden to perform analysis.");
			return false;
		}
	}
	
	public void performAnalysis(GButton button, GEvent event) { 
		performAnalysis();
	}
	
	public void textfield1_change1(GTextField source, GEvent event) {
		println("textfield1 - GTextField >> GEvent." + event + " @ " + millis());
	}

	
	public void createGUI(){
		G4P.messagesEnabled(false);
		G4P.setGlobalColorScheme(GCScheme.GREEN_SCHEME);
		G4P.setCursor(ARROW);
		if(frame != null){
			frame.setTitle("Stegnos Library Demonstrator");
			frame.setLocation(winX, winY);
		}
		lblAppTitle = new GLabel(this, 10, 10, 280, 30);
		lblAppTitle.setFont(new java.awt.Font("Sans Serif", Font.PLAIN, 18));
		lblAppTitle.setText("Steganograph Creator");
		lblAppTitle.setTextBold();
		lblAppTitle.setOpaque(true);
		lblAppTitle.setLocalColorScheme(GCScheme.GOLD_SCHEME);

		GButton b = new GButton(this, 10, 54, 240, 22);
		b.setText("Carrier Image Selector");
		b.setTextBold();
		GImageToggleButton tb = new GImageToggleButton(this, 260, 50, statusIconFile, 2, 1);
		carrierSelector = new Selector(this, b, tb, "Carrier image", "png,gif,jpg,jpeg,tiff", "Image Files");	
		b.addEventHandler(carrierSelector, "change");
		tb.addEventHandler(carrierSelector, "invalidate");
		
		b = new GButton(this, 10, 94, 240, 22);
		b.setText("Burden Selector");
		b.setTextBold();
		tb = new GImageToggleButton(this, 260, 90, statusIconFile, 2, 1);
		burdenSelector = new Selector(this, b, tb, "Burden image / text", "txt,png,gif,jpg,jpeg,tiff", "Burden Files");
		b.addEventHandler(burdenSelector, "change");
		tb.addEventHandler(burdenSelector, "invalidate");


		btnAnalysis = new GButton(this, 10, 130, 280, 20);
		btnAnalysis.setText("Perform Steganography Analysis");
		btnAnalysis.addEventHandler(this, "performAnalysis");

		lblAnalysis = new GLabel(this, 10, 160, 280, 200);
		lblAnalysis.setText("");
		lblAnalysis.setOpaque(true);
		lblAnalysis.setTextAlign(GAlign.LEFT, GAlign.TOP);
		lblAnalysis.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 11));
		
		lblPassword = new GLabel(this, 10, 378, 280, 20);
		lblPassword.setText("Password or pass-phrase");
		lblPassword.setTextBold();
		lblPassword.setOpaque(true);
		txfPassword = new GTextField(this, 10, 400, 280, 30, G4P.SCROLLBARS_HORIZONTAL_ONLY);
		txfPassword.setPromptText("No pass-phrase, no encryption");
		txfPassword.setOpaque(true);
		txfPassword.addEventHandler(this, "textfield1_change1");

		b = new GButton(this, 10, 454, 240, 22);
		b.setText("Create Steganograph");
		b.setTextBold();
		tb = new GImageToggleButton(this, 260, 450, statusIconFile, 2, 1);
		steganSelector = new Selector(this, b, tb, "Steganograph", "png,gif,jpg,jpeg,tiff", "Image Files");
		tb.addEventHandler(steganSelector, "invalidate");
		b.addEventHandler(steganSelector, "makeStegan");

		b = new GButton(this, 10,484, 280, 22);
		b.setText("Save Steganograph");
		b.setTextBold();
		b.addEventHandler(steganSelector, "saveStegan");
	}

	// Variable declarations 
	// autogenerated do not edit
	GLabel lblAppTitle, lblPassword, lblAnalysis;
	
	GButton btnAnalysis, btnSave; 
	GTextField txfPassword; 

}
